package com.yj.serial_port.util;

import android.serialport.SerialPort;
import android.serialport.SerialPortFinder;
import android.util.Log;


import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

public class SerialPortHelper {

    private static String TAG = "SerialPortHelper";

    private static SerialPortHelper serialPortHelper;
    private SerialPort serialPort;
    private InputStream inputStream;
    private ReadThread readThread;
    private SerialPortCallback callback;

    public void setCallback(SerialPortCallback callback) {
        this.callback = callback;
    }

    public interface SerialPortCallback{
        void onDataReceived(byte[] buffer, int size);
    }

    private SerialPortHelper(String path, int baudrate) throws IOException {
        serialPort = new SerialPort(new File(path), baudrate);
    }
    public static SerialPortHelper getInstance(String path, int baudrate) throws IOException{
        if(serialPortHelper == null){
            serialPortHelper = new SerialPortHelper(path, baudrate);
        }
        return serialPortHelper;
    }

    public void close(){
        if(readThread != null){
            readThread.interrupt();
            readThread = null;
        }
//        System.out.println("serialPort "+ serialPort);
        if(serialPort != null){
            serialPort.tryClose();
//            serialPort.close();
            serialPort = null;
            serialPortHelper = null;
        }

    }

    public static String[] getAllDevicesPath(){
        String[] devices = new SerialPortFinder().getAllDevicesPath();
        for(String str : devices) {
            Log.e(TAG, str);
        }
        return devices;
    }

    public void startReceive(){
        Log.e(TAG, "start receive");
        if(serialPort != null){
            inputStream = serialPort.getInputStream();
            readThread = new ReadThread();
            readThread.start();
        }

    }

    private byte[] actualBuffer = new byte[0];
    class ReadThread extends Thread{
        @Override
        public void run() {
            super.run();
            while (!isInterrupted()){
                try{
                    if(inputStream == null){
                        LogUtils.e("input stream is null");
                        return;
                    }
                    byte[] buffer = new byte[1024];
                    int len = inputStream.read(buffer);
                    if(len > 0){
                        actualBuffer = concat(actualBuffer,
                                Arrays.copyOfRange(buffer, 0, len));
                    }
//                    if(actualBuffer.length >= 12){
//                        if(callback != null){
//                            callback.onDataReceived(
//                                    Arrays.copyOfRange(actualBuffer, 0, 12),
//                                    12
//                            );
//                        }
//                        actualBuffer = Arrays.copyOfRange(
//                                actualBuffer, 12, actualBuffer.length);
//                    }
                    if(actualBuffer.length > 0){
//                        for(byte b : actualBuffer){
//                            LogUtils.v("b "+ b);
//                        }
                        if(callback != null){
                            callback.onDataReceived(actualBuffer, actualBuffer.length);
                        }
                        actualBuffer = new byte[0];
                    }
//                    LogUtils.v("actualBuffer len" + actualBuffer.length);
                }catch (Exception e){
                    e.printStackTrace();
                    return;
                }
            }
        }
    }

    private byte[] concat(byte[] a, byte[] b){
        byte[] c = new byte[a.length + b.length];
        System.arraycopy(a, 0, c, 0, a.length);
        System.arraycopy(b, 0, c, a.length, b.length);
        return c;
    }
}
